package com.sniper.web.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sniper.data.BaseData;
import com.sniper.data.Constants;
import com.sniper.model.AdminGroup;
import com.sniper.model.AdminUser;
import com.sniper.mybatis.service.impl.AdminUserService;
import com.sniper.utils.ValidateUtil;
import com.sniper.web.listener.SpringContextUtil;
import com.sniper.web.redis.RedisConnUtil;
import com.sniper.web.shiro.filter.KickoutSessionControlFilter;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;

import java.io.IOException;
import java.util.List;

/**
 * 当用户登录空的时候这里会出错
 *
 * @author suzhen
 */
public class UserDetailsUtils {

    static RedisConnUtil jedisConnectionFactory;

    static {
        jedisConnectionFactory = SpringContextUtil.getBean(RedisConnUtil.class);
    }

    static CacheManager cacheManager;

    static {
        cacheManager = SpringContextUtil.getBean("ehCacheManager");
    }

    private static AdminUserService adminUserService;

    static {
        adminUserService = SpringContextUtil.getBean(AdminUserService.class);
    }

    private Subject subject = SecurityUtils.getSubject();
    private String realmName = "myRealm";

    public UserDetailsUtils() {

    }

    public UserDetailsUtils(String realmName) {
        this.realmName = realmName;
    }


    public Subject getSubject() {
        return subject;
    }

    public String getPrincipal() {
        PrincipalCollection principalCollection = subject.getPrincipals();
        if (subject.isAuthenticated() && !principalCollection.isEmpty()) {
            return principalCollection.getPrimaryPrincipal().toString();
        }
        return null;
    }


    /**
     * 判断用户是否拥有某个角色的权限 <shiro:hasRole name="admin"> <!— 有权限 —> </shiro:hasRole>
     *
     * @param role
     * @return
     * @RequiresRoles("admin") 作用于方法 属于粗的控制
     */
    public boolean validRole(String role) {
        return subject != null && subject.hasRole(role);
    }

    /**
     * 判断用户是否拥有某个用户组
     *
     * @param role
     * @return
     */
    public boolean hasRole(String role) {
        AdminUser adminUser = getAdminUser();
        if (adminUser != null) {
            List<AdminGroup> adminGroups = adminUser.getAdminGroup();
            for (AdminGroup adminGroup : adminGroups) {
                if (adminGroup.getValue().equals(role)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 为了
     *
     * @return
     */
    public AdminUser getAdminUser() {
        AdminUser adminUser = null;
        String principal = getPrincipal();
        if (!ValidateUtil.isValid(principal)) {
            return null;
        }
        Session session = subject.getSession();
        //当用户runAs的时候就不能读取这个session了
        if (!subject.isRunAs()) {
            adminUser = (AdminUser) session.getAttribute(Constants.CURRENT_USER.toString() + principal);
        }

        if (adminUser == null && StringUtils.isNotBlank(principal)) {
            adminUser = adminUserService.getUserAndGroupAndRight(principal);
            session.setAttribute(Constants.CURRENT_USER.toString() + principal, adminUser);
            return adminUser;
        }
        return adminUser;
    }

    /**
     * 返回用户拥有的处室
     *
     * @param siteid
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<Integer> getSiteid(String siteid) {

        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(siteid, List.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 退出
     */
    public void logout() {

        if (subject.getPrincipal() != null) {
            // 删除和用户相关的数据
            String keyPrefix = BaseData.USER_PREFIX + getPrincipal();
            // 删除和用户所有有关的缓存
            jedisConnectionFactory.delKeys(keyPrefix + "*");
            //清空登录拦截器中生成的缓存，如果不清除，在缓存有效期内，其他人登不进去
            cacheManager.getCache(KickoutSessionControlFilter.CACHE_NAME).remove(getPrincipal());
            subject.logout();
        }
    }
}